<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body style="height: 10000px;">
    <input id="input" type="text">
    <!-- 防抖 -->
    <script>
        input.oninput = fangdou(function () {
            console.log(this.value);
        }, 500);
        // 防抖
        function fangdou(fn, delay = 500) {
            let time = null;
            return function () {
                let _this = this;
                let args = arguments;
                if (time !== null) {
                    clearTimeout(time);
                }
                time = setTimeout(function () {
                    fn.call(_this, args);
                }, delay);
            }
        }
        // 防抖（在最后一次操作的时间节点到了才执行，如果时间没到，又执行了多次，则会重新计算延迟时间）
        function dou(fn, delay) {
            let time = null;
            return function () {
                const that = this;
                const args = arguments;
                // 每次进来判断有没有正在运行的定时器，有就取消掉，取消之后会新生成一个定时器，再重新计算延迟时间后执行fn
                if (time !== null) {
                    clearTimeout(time)
                }
                time = setTimeout(function () {
                    fn.call(that, args)
                }, delay);
            }
        }
    </script>
    <!-- 节流 -->
    <script>
        document.onscroll = jieliu(function () {
            console.log(1);
        }, 500);
        // 节流
        function jieliu(fn, delay = 500) {
            let flag = true;
            return function () {
                let _this = this;
                let args = arguments;
                if (!flag) {
                    return;
                }
                flag = false;
                setTimeout(function () {
                    fn.call(_this, args);
                    flag = true;
                }, delay);
            }
        }
        // 节流（每隔一段时间执行一次）
        function jie(fn, delay) {
            // 定义一个开关，用来隔一段时间开一下，默认是开启状态
            let flag = true;
            return function () {
                let that = this;
                let args = arguments;
                // 如果下次进来，开关是关的，则返回，否则就把开关关掉，然后延迟时间执行fn，执行完fn后把开关打开
                if (!flag) {
                    return;
                }
                flag = false;
                setTimeout(function () {
                    fn.call(that, args);
                    // 重新开启开关，用来在下一个延迟时间到了之后能正常再执行一遍
                    flag = true;
                }, delay)
            }
        }
    </script>
    <!-- copilot生成的代码 -->
    <script>
        // 防抖函数
        function debounce(fn, delay) {
            // 定义一个变量来存储定时器的 ID
            let timer = null;
            // 返回一个新的函数
            return function () {
                // 保存当前的上下文（this）
                let that = this;
                // 保存当前的参数
                let args = arguments;
                // 如果定时器已经存在，清除它
                if (timer !== null) {
                    clearTimeout(timer);
                }
                // 设置一个新的定时器
                timer = setTimeout(function () {
                    // 在定时器到期时调用传入的函数，并传递上下文和参数
                    fn.call(that, args);
                }, delay);
            }
        }
        // 节流函数
        function throttle(fn, delay) {
            // 定义一个标志位，用于控制函数的执行
            let flag = true;
            // 返回一个新的函数
            return function () {
                // 保存当前的上下文（this）
                let that = this;
                // 保存当前的参数
                let args = arguments;
                // 如果标志位为 false，直接返回，不执行函数
                if (!flag) {
                    return;
                }
                // 将标志位设为 false，阻止函数的再次执行
                flag = false;
                // 设置一个定时器，在指定的延迟时间后执行函数
                setTimeout(function () {
                    // 在定时器到期时调用传入的函数，并传递上下文和参数
                    fn.call(that, args);
                    // 将标志位重新设为 true，允许函数的再次执行
                    flag = true;
                }, delay);
            }
        }

        // // 使用防抖函数
        // input.oninput = fangdou(function () {
        //     console.log(this.value);
        // }, 500);
        // // 使用节流函数
        // document.onscroll = throttle(function () {
        //     console.log(Math.random());
        // }, 500);

    </script>
</body>

</html>